import Request from "luch-request";
import baseConfig from "@/common/config";
import store from "@/store";
/**
 * luch-request 文档参考
 * https://www.quanzhan.co/luch-request/guide/3.x/#%E5%8F%AF%E9%85%8D%E7%BD%AE%E9%A1%B9
 */
const http = new Request();

/**
 * @description 修改全局默认配置
 */
http.setConfig((config) => {
  /* config 为默认全局配置*/
  // let baseURL = import.meta.env.VITE_BASE_API || "";
  // let prefix = import.meta.env.VITE_PREFIX_API || "";
  const baseURL = baseConfig.baseUrl || "";
  const prefix = baseConfig.prefix || "";
  // console.log("baseURL:", baseURL, prefix);
  let finalUrl = baseURL;
  // #ifdef H5
  // 如果是h5开发环境，则使用代理
  finalUrl = baseURL + prefix;
  // 注意 ： 此处需要兼顾h5开发环境下，需要代理的接口，以及生产环境直接访问的接口
  if (import.meta.env.DEV) {
    finalUrl = prefix;
  }
  // #endif
  // #ifndef H5
  // 如果是非h5开发环境，则直接使用baseURL (prefix 只用于前端代理，实际后端请求不需要，所以此处不使用)
  finalUrl = baseURL + prefix;
  // #endif
  config.baseURL = finalUrl; /* 根域名 */
  config.header = {
    Authorization: "Basic c2FiZXI6c2FiZXJfc2VjcmV0", // 固定
    "Content-Type": "application/json;charset=UTF-8",
    "is-Detail": "2", //去掉脱敏
    "Pay-Code": "SOJOURN_PAY",
    "Is-App": "1",
    "Tenant-Id": baseConfig.getTenantId(),
  };
  return config;
});

/**
 * @interceptWhiteList 拦截白名单
 在接口请求配置中 往header中添加 noVerify: true，
 * 请求拦截中判断，如果存在 noVerify: true 则不进行检查直接返回数据
 */
const interceptWhiteList = new Map();

// 请求拦截
http.interceptors.request.use(
  (config) => {
    // 添加 token
    if (store.getters.token) {
      // @ts-ignore
      config.header["Kingon-Auth"] = "bearer " + store.getters.token;
    }

    // 判断是否加入拦截白名单
    // @ts-ignore
    if (config.header.noVerify == true) {
      interceptWhiteList.set(config.url, true);
    }

    return config;
  },
  (config) => {
    // 可使用async await 做异步操作
    return Promise.reject(config);
  }
);

// HTTPresponse  响应拦截
http.interceptors.response.use(
  (response) => {
    /* 对响应成功做点什么 可使用async await 做异步操作*/
    // console.log("response:", response, interceptWhiteList);
    // apiData 是 API 返回的数据
    const apiData = response.data;
    // 这个 Code 是和后端约定的业务 Code
    const code = apiData?.code;

    // 判断是否拦截白名单
    if (interceptWhiteList.get(response.config.url)) {
      return Promise.resolve(apiData);
    }

    // 如果没有 Code, 代表这不是项目后端开发的 API （除特殊接口外）
    if (code === undefined) {
      return Promise.reject(new Error("非本系统的接口"));
    } else {
      // 处理与后端约定的业务 Code
      switch (Number(code)) {
        case 200:
          // code === 200 代表没有错误
          return apiData;
        case 407:
          uni.showToast({
            title: apiData.message || "Error",
            icon: "none",
          });
          return Promise.reject(apiData);
        case 401: // 登录过期
          uni.showToast({
            title: apiData.message || "登录过期",
            icon: "none",
          });

          return;
        default:
          if (apiData.message != "没有此应用") {
            uni.showToast({
              title: apiData.message || "Error",
              icon: "none",
            });
          }
          return Promise.reject(apiData);
      }
    }
  },
  (response: any) => {
    /*  对响应错误做点什么 （statusCode !== 200）*/
    // Status 是 HTTP 状态码
    const status = response.statusCode;
    switch (status) {
      case 400:
        // #1 接口消息-接口返回数据不统一 做兼容处理
        const { msg, error_description } = response.data;
        let message = msg || error_description || "请求错误";
        response.message = message;
        break;
      case 401:
        // Token 过期时，直接退出登录并强制刷新页面（会重定向到登录页）
        console.log("> request 401 ", response);
        if (response.data.data == "un_bind_phone_ip") {
          return Promise.resolve(response.data);
        }
        if (response.config?.header?.isReLaunch != false) {
          return store.dispatch("user/logout", { isReLaunch: true });
        }
        break;
      case 403:
        response.message = "拒绝访问";
        break;
      case 404:
        response.message = "请求地址出错";
        break;
      case 408:
        response.message = "请求超时";
        break;
      case 500:
        response.message = "服务器内部错误";
        break;
      case 501:
        response.message = "服务未实现";
        break;
      case 502:
        response.message = "网关错误";
        break;
      case 503:
        response.message = "服务不可用";
        break;
      case 504:
        response.message = "网关超时";
        break;
      case 505:
        response.message = "HTTP 版本不受支持";
        break;
      default:
        break;
    }
    if (response.message)
      uni.showToast({
        title: response.message,
        icon: "none",
      });
    return Promise.reject(response);
  }
);

/** 创建请求方法 */
function createRequestFunction(
  serviceInstance: Request,
  type: 'request' | 'upload' | 'download'
) {
  return (config: any) => {
    const configDefault = {
      ...serviceInstance.config,
    };
    // 合并默认配置
    switch (type) {
      case 'request':
        return serviceInstance.middleware(Object.assign(configDefault, config));
      case 'upload':
        return serviceInstance.upload(
          config.url,
          Object.assign(configDefault, config)
        );
      case 'download':
        return serviceInstance.download(
          config.url,
          Object.assign(configDefault, config)
        );
    }
  };
}

/** 用于网络请求的实例 */
export const service = http;
/** 用于网络请求的方法 */
export const request = createRequestFunction(service, 'request');
/** 用于上传资源的方法 */
export const upload = createRequestFunction(service, 'upload');
/** 用于下载资源的方法 */
export const download = createRequestFunction(service, 'download');
